package me.luger.core.auth.cookie.interceptor;

import me.luger.core.auth.cookie.annotation.CookieAuth;
import me.luger.core.auth.cookie.annotation.IgnoreCookieAuth;
import me.luger.core.auth.cookie.util.CookieAuthUtil;
import me.luger.core.commom.util.*;
import me.luger.core.dao.cache.redis.springdata.RedisManager;
import me.luger.core.mvc.entity.Result;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.env.Environment;
import org.springframework.stereotype.Component;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.lang.reflect.Method;
import java.util.Map;

/**
 * Created by luger on 2017/5/10.
 */
@Component
public class CookieAuthInterceptor implements HandlerInterceptor {

    @Autowired
    private Environment env;

    @Autowired(required = false)
    private RedisManager redisManager;

    @Override
    public boolean preHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object handler) throws Exception {
        HandlerMethod handlerMethod = (HandlerMethod) handler;
        Method method = handlerMethod.getMethod();
        Class<?> clazz = method.getDeclaringClass();
        CookieAuth cookieAuth = clazz.getAnnotation(CookieAuth.class);


        CookieAuth methodCookieAuth = method.getAnnotation(CookieAuth.class);
        if(null != methodCookieAuth){
            cookieAuth = methodCookieAuth;
        }

        IgnoreCookieAuth ignoreCookieAuth = method.getAnnotation(IgnoreCookieAuth.class);

//        LogUtil.infoLog("cookie cookieAuth = " + cookieAuth);
//        LogUtil.infoLog("cookie ignoreCookieAuth = " + ignoreCookieAuth);
        if (cookieAuth != null && null == ignoreCookieAuth) {
            Map<String,String> cookieMap = CookieAuthUtil.getAuthCookie(httpServletRequest);

//            LogUtil.infoLog("cookie cookieMap = " + JsonUtil.toString(cookieMap));

            if(null == cookieMap){
                processAuthFail(httpServletRequest,httpServletResponse,cookieAuth);
                return false;
            }
            String ip = HttpUtil.getRemoteAddr(httpServletRequest);
            String ipFromCookie = cookieMap.get("ip");
//            LogUtil.infoLog("cookie ip = " + ip);
//            LogUtil.infoLog("cookie ipFromCookie = " + ipFromCookie);
            if(StringUtil.isNotBlank(ipFromCookie) && StringUtil.isNotBlank(ip) && ipFromCookie.equals(ip)){
                return true;
            }else{
                processAuthFail(httpServletRequest,httpServletResponse,cookieAuth);
                return false;
            }
        }
        return true;
    }

    @Override
    public void postHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, ModelAndView modelAndView) throws Exception {

    }

    @Override
    public void afterCompletion(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, Exception e) throws Exception {

    }


    private void processAuthFail(HttpServletRequest request, HttpServletResponse response,CookieAuth cookieAuth){
        String directUrl = cookieAuth.directUrl();
        Integer retCode = cookieAuth.retCode();

        if(StringUtil.isNotBlank(directUrl)){
            try {
                response.sendRedirect(directUrl);
                return;
            } catch (IOException e) {
                LogUtil.errorLog(e,"user auth by cookie failed and redirect failed too");
            }
        }else{
            String callback = request.getParameter("callback");
            String retContent = JsonUtil.toString(Result.info(retCode,"auth fail"));
            response.setCharacterEncoding("UTF-8");
            try {
                if(StringUtil.isNotBlank(callback)){
                    retContent = String.format("%s(%s)",callback,retContent);
                }
                response.getWriter().write(retContent);
                return;
            } catch (IOException e) {
                LogUtil.errorLog(e,"user auth by cookie failed and return json failed too");
            }
        }


    }
}
